#include "my_vector.hpp"

using namespace zq;
// 迭代器的实现
//如果my_vector是一个模板类，那么需要确保模板的定义对编译器可见，
//也就是要在源文件中显示的实例化对应的数据类型的模板

template class zq::my_vector<int>; // 显式实例化 int 类型的模板
//template class zq::my_vector<string>; // 显式实例化 int 类型的模板
template class zq::my_vector<float>; // 显式实例化 int 类型的模板
template class zq::my_vector<double>; // 显式实例化 int 类型的模板
template class zq::my_vector<long long>; // 显式实例化 int 类型的模板


template <class T>
T* my_vector<T>::begin()
{
    return _start;
}
template <class T>
T* my_vector<T>::end()
{
    return _finish;
}
template <class T>
const T* my_vector<T>::begin() const
{
    return _start;
}
template <class T>
const T* my_vector<T>::end() const
{
    return _finish;
}
template <class T>
my_vector<T>::my_vector() : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
{
}
template <class T>
void my_vector<T>::reserve(size_t n)
{
    if (n > capacity())
    {
        size_t sz = size();
        T *tmp = new T[n];
        if (_start)
        {
            // memcpy(tmp, _start, sizeof(T) * sz);
            for (size_t i = 0; i < sz; i++)
            {
                tmp[i] = _start[i]; // 这里调用的是T的operator= 深拷贝
            }
            delete[] _start;
        }
        _start = tmp;
        _finish = tmp + sz;
        _end_of_storage = tmp + n;
    }
}
template <class T>
void my_vector<T>::push_back(const T &x)
{
    // 首先考虑扩容
    if (_finish == _end_of_storage)
    {
        size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;
        reserve(newcapacity);
    }

    *_finish = x;
    ++_finish;
}
template <class T>
void my_vector<T>::insert(iterator pos, const T &x)
{
    assert(pos <= _finish); // 如果在finish位置插入就是尾插
    // 同样先考虑扩容问题
    size_t newpos = pos - _start;
    if (_finish == _end_of_storage)
    {
        size_t newcapacity = capacity() == 0 ? 2 : capacity() * 2;
        reserve(newcapacity);
    }

    pos = _start + newpos;
    iterator end = _finish - 1;
    while (end >= pos)
    {
        *(end + 1) = *end;
        --end;
    }
    *pos = x;
    _finish++;
}
template <class T>
T* my_vector<T>::erase(T* pos)
{
    assert(pos < _finish);
    T* cur = pos;
    while (cur < _finish)
    {
        *cur = *(cur + 1);
        cur++;
    }
    --_finish;
    return pos; // 返回的是当前位置的下一个位置
}
template <class T>
void my_vector<T>::pop_back()
{
    assert(_start < _finish);
    --_finish;
}
template <class T>
void my_vector<T>::resize(size_t n, const T &val)
{
    if (n < size())
    {
        _finish = _start + n;
    }
    else
    {
        if (n > capacity())
        {
            reserve(n);
        }
        while (_finish < _start + n)
        {
            *_finish = val;
            ++_finish;
        }
    }
}
template <class T>
my_vector<T>::my_vector(const my_vector<int> &v) : _start(nullptr), _finish(nullptr), _end_of_storage(nullptr)
{
    reserve(v.capacity()); // 先开辟一样答的空间
    for (const auto &e : v)
    {
        push_back(e); // 依次插入到新的vector中
    }
}
template <class T>
my_vector<T>& my_vector<T>::operator=(my_vector<T> v)
{
    std::swap(_start, v._start);
    std::swap(_finish, v._finish);
    std::swap(_end_of_storage, v._end_of_storage);
    return *this;
}
template <class T>
void my_vector<T>::print_vector()
{
    my_vector<T>::const_iterator it = begin();
    while (it != end())
    {
        std::cout << *it << " ";
        ++it; // 原生指针不用重载++运算符
    }
    std::cout << std::endl;
}
template <class T>
size_t my_vector<T>::size()
{
    return _finish - _start;
}
template <class T>
size_t my_vector<T>::capacity()
{
    return _end_of_storage - _start;
}
template <class T>
size_t my_vector<T>::size() const
{
    return _finish - _start;
}
template <class T>
size_t my_vector<T>::capacity() const
{
    return _end_of_storage - _start;
}
template <class T>
my_vector<T>::~my_vector<T>()
{
    delete[] _start;
    _start = _finish = _end_of_storage = nullptr;
}
